home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 1
/
Cream of the Crop 1.iso
/
PRINTER
/
JPSRC11.ARJ
/
JETD2L.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-08-04
|
15KB
|
490 lines
/*
* JET PAK - HP DeskJet and LaserJet series printer utilities
*
* JETD2L program - convert from DeskJet to LaserJet soft font file
*
* Version 1.1 (Public Domain)
*/
/* system include files */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
/* application include files */
#include "patchlev.h"
#include "jetfont.h"
#include "jetutil.h"
#include "jetbmp.h"
/*
* MODULE GLOBAL DATA
*/
/* baseline distance for bottom pass */
static UNSIGNEDINT baseline;
/* pitch is needed for converting landscape characters */
static UNSIGNEDINT pitch;
/* height to use for all characters */
static UNSIGNEDINT cell_height;
/* offsets for passes */
static UNSIGNEDINT offsets[4];
/* portrait or landscape font */
static UNSIGNEDBYTE orientation;
/* fixed or proportional spacing font */
static UNSIGNEDINT spacing;
/* input and output font commands being processed */
static FONT_COMMAND infc, outfc;
/* output file suffix */
static char output_suffix[SUFFIX_MAX] = ".d2l";
/* compact bitmap structure */
typedef struct compact_ljchar_struct {
SIGNEDINT left_offset;
SIGNEDINT top_offset;
UNSIGNEDINT character_width;
UNSIGNEDINT character_height;
SIGNEDINT delta_x;
UNSIGNEDBYTE *bitmap;
} COMPACT_LJCHAR;
static COMPACT_LJCHAR ljchars[256] = { 0 };
#define sizeofljbitmap(w,h) (((w + 7)/8)*h)
/*
* LOCAL FUNCTIONS
*/
static void usage_wrong()
{
/*
* Print usage message and exit.
*/
fprintf(stderr, USAGE_HEADER);
fprintf(stderr, "Usage: JETD2L [-h] [-t filetype] djfontfile [djfontfile...]\n\n");
fprintf(stderr, "Convert DeskJet font files to LaserJet format\n\n");
fprintf(stderr, " -h print this usage information\n");
fprintf(stderr, " -t filetype change output file type (default %s)\n", output_suffix);
fprintf(stderr, " djfontfile name of DeskJet format soft font file to be converted\n");
exit(1);
}
static int ljchar_create(charcode, infcp)
UNSIGNEDINT charcode;
FONT_COMMAND *infcp;
{
/*
* Copy the information in a DeskJet character descriptor to
* a compact LaserJet character structure, allocating space
* for the bitmap if necessary.
*/
struct djchar_struct *djp;
UNSIGNEDINT height;
int pass;
/* issue a warning if the character descriptor is in a strange format */
if ( (infcp->data.character.format != DJCHARFORMAT)
&& (infcp->data.character.format != DJPCHARFORMAT)
&& (infcp->data.character.format != DJ500CHARFORMAT) )
fprintf(stderr, WARNING_BAD_CHAR_FORMAT,
os_dir, os_file, infcp->data.character.format);
/* check the character code is in range */
if (charcode >= sizeofarray(ljchars))
{
fprintf(stderr, ERROR_CODE_TOO_BIG, os_dir, os_file, charcode);
return(ERROR);
}
/* OK to save the information */
djp = &infcp->data.character.data.djchar;
switch (djp->char_type)
{
case CHAR_TYPE_NORMAL:
case CHAR_TYPE_PASS1:
if (orientation == LANDSCAPE)
{
ljchars[charcode].left_offset = djp->comp_width/2 - baseline;
ljchars[charcode].top_offset = pitch;
ljchars[charcode].character_width = djp->character_width/2;
ljchars[charcode].character_height = pitch;
ljchars[charcode].delta_x = pitch*4;
}
else
{
ljchars[charcode].top_offset = baseline;
ljchars[charcode].character_width = djp->character_width/2;
ljchars[charcode].character_height = cell_height;
if (spacing == FIXED)
{
ljchars[charcode].delta_x = pitch*4;
ljchars[charcode].left_offset = ((SIGNEDINT)(pitch - djp->character_width/2))/2;
}
else
{
ljchars[charcode].delta_x = 2 * ( djp->right_offset
+ djp->left_offset
+ djp->character_width);
ljchars[charcode].left_offset = djp->left_offset/2;
}
}
if ((ljchars[charcode].bitmap =
zalloc(sizeofljbitmap(ljchars[charcode].character_width, ljchars[charcode].character_height))) == NULL)
{
fprintf(stderr, ERROR_FONT_OUT_OF_HEAP, os_dir, os_file);
return(ERROR);
}
/* !! intentional drop-through !! */
default:
pass = pass_for_char_type(djp->char_type) % sizeofarray(offsets);
height = ljchars[charcode].character_height - offsets[pass];
if (height > PASS_HEIGHT)
height = PASS_HEIGHT;
if (bitmap_dj_to_lj(djp->bitmap, djp->character_width, height,
offsets[pass], ljchars[charcode].bitmap,
sizeofljbitmap(ljchars[charcode].character_width,
ljchars[charcode].character_height)) != OK)
{
fprintf(stderr, ERROR_BITMAP_TOO_BIG, os_dir, os_file);
return(ERROR);
}
}
return(OK);
}
static void ljchar_free_all()
{
/*
* Free the resources used in all the compact LaserJet characters.
*/
UNSIGNEDINT charcode;
for (charcode = 0; charcode < sizeofarray(ljchars); charcode++)
{
if (ljchars[charcode].bitmap != NULL)
{
free(ljchars[charcode].bitmap);
ljchars[charcode].bitmap = NULL;
}
}
}
static int fdc_dj_to_lj(infcp, outfcp)
FONT_COMMAND *infcp, *outfcp;
{
/*
* Convert a DeskJet font descriptor command to a LaserJet font
* descriptor command.
*/
int passes;
FONT_DESCRIPTOR *fdp;
/* check input file is in correct format */
if (infcp->data.font.header_format == LJFONTFORMAT)
{
fprintf(stderr, ERROR_LASERJET, os_dir, os_file);
return(ERROR);
}
else if ( (infcp->data.font.header_format != DJFONTFORMAT)
&& (infcp->data.font.header_format != DJPFONTFORMAT)
&& (infcp->data.font.header_format != DJ500FONTFORMAT) )
{
fprintf(stderr, WARNING_BAD_FONT_FORMAT,
os_dir, os_file, infcp->data.font.header_format);
}
outfcp->command_type = infcp->command_type;
outfcp->number = LJFDSIZE+LJSSIZE;
/* most of the font descriptor fields can be copied straight
across */
outfcp->data.font = infcp->data.font;
/* now change the standard font descriptor bits that are different */
fdp = &outfcp->data.font;
fdp->header_format = LJFONTFORMAT;
fdp->size = LJFDSIZE;
/* convert the bitmap related data - depends on orientation */
if (fdp->orientation == LANDSCAPE)
{
fdp->cell_height /= 2; /* -> 300 dpi in X direction */
/* must be a single pass font */
passes = 1;
offsets[0] = 0;
offsets[1] = 0;
offsets[2] = 0;
offsets[3] = 0;
}
else /* PORTRAIT */
{
/* save the pass offsets */
if (fdp->baseline_offset_4 != 0)
{
passes = 4;
offsets[0] = fdp->baseline_offset_4 - fdp->baseline_distance;
offsets[1] = fdp->baseline_offset_4 - fdp->baseline_offset_2;
offsets[2] = fdp->baseline_offset_4 - fdp->baseline_offset_3;
offsets[3] = 0;
fdp->baseline_distance = fdp->baseline_offset_4;
}
else if (fdp->baseline_offset_3 != 0)
{
passes = 3;
offsets[0] = fdp->baseline_offset_3 - fdp->baseline_distance;
offsets[1] = fdp->baseline_offset_3 - fdp->baseline_offset_2;
offsets[2] = 0;
offsets[3] = 0;
fdp->baseline_distance = fdp->baseline_offset_3;
}
else if (fdp->baseline_offset_2 != 0)
{
passes = 2;
offsets[0] = fdp->baseline_offset_2 - fdp->baseline_distance;
offsets[1] = 0;
offsets[2] = 0;
offsets[3] = 0;
fdp->baseline_distance = fdp->baseline_offset_2;
}
else
{
passes = 1;
offsets[0] = 0;
offsets[1] = 0;
offsets[2] = 0;
offsets[3] = 0;
}
fdp->cell_width /= 2; /* -> 300 dpi in X direction */
fdp->cell_height = offsets[0] + PASS_HEIGHT;
}
/* save parameters needed in character descriptor processing */
baseline = fdp->baseline_distance;
pitch = fdp->pitch/4;
orientation = fdp->orientation;
cell_height = fdp->cell_height;
spacing = fdp->spacing;
/* add identifying suffix to existing copyright notice */
if ((strlen(fdp->comment) + sizeof(JETD2L_COMMENT_SUFFIX)) < COMMENT_SIZE_MAX)
strcat(fdp->comment, JETD2L_COMMENT_SUFFIX);
outfcp->number += strlen(fdp->comment);
return(passes);
}
static int cdc_dj_to_lj(inccp, outfcp)
COMPACT_LJCHAR *inccp;
FONT_COMMAND *outfcp;
{
/*
* Copy a compact LaserJet character to a real LaserJet character
* descriptor.
*/
struct ljchar_struct *ljp;
outfcp->command_type = CDC;
/* deal with the preamble bits */
outfcp->data.character.format = LJCHARFORMAT;
outfcp->data.character.continuation = 0;
/* deal with the character descriptor proper */
ljp = &outfcp->data.character.data.ljchar;
ljp->descriptor_size = LJCDSIZE;
ljp->class = 1;
ljp->orientation = orientation;
ljp->reserved = 0;
ljp->left_offset = inccp->left_offset;
ljp->top_offset = inccp->top_offset;
ljp->character_width = inccp->character_width;
ljp->character_height = inccp->character_height;
ljp->delta_x = inccp->delta_x;
memcpy(ljp->bitmap, inccp->bitmap,
sizeofljbitmap(ljp->character_width, ljp->character_height));
outfcp->number = 2 + LJCDSIZE + sizeofljbitmap(ljp->character_width, ljp->character_height);
return(OK);
}
static void jetd2l()
{
char inpath[OS_PATH_LEN], outpath[OS_PATH_LEN], *sp;
FILE *infp, *outfp;
int r, npasses = 0;
UNSIGNEDINT charcode;
/* build the input and output file paths */
strcpy(inpath, os_dir);
strcat(inpath, os_file);
strcpy(outpath, os_file);
if ((sp = strrchr(outpath, '.')) == NULL)
strcat(outpath, output_suffix);
else
strcpy(sp, output_suffix);
/* rudimentary check for input overwriting output */
if (strcmp(inpath, outpath) == 0)
{
fprintf(stderr, ERROR_OVERWRITE, os_dir, os_file);
return;
}
if (!(infp = fopen(inpath, "rb")))
{
fprintf(stderr, ERROR_OPEN_READ_FAILED, os_dir, os_file);
return;
}
if (!(outfp = fopen(outpath, "wb")))
{
fprintf(stderr, ERROR_OPEN_WRITE_FAILED, os_dir, os_file, outpath);
fclose(infp);
return;
}
/* copy the font header and load the characters into memory */
while ((r = font_command_read(infp, &infc)) == OK)
{
switch(infc.command_type)
{
case FDC:
if ((npasses = fdc_dj_to_lj(&infc, &outfc)) == ERROR)
{
ljchar_free_all();
fclose(infp);
fclose(outfp);
return;
}
if (font_command_write(outfp, &outfc) == ERROR)
{
fprintf(stderr, ERROR_FILE_WRITE_FAILED, os_dir, os_file);
ljchar_free_all();
fclose(infp);
fclose(outfp);
return;
}
break;
case CCC:
charcode = infc.number;
break;
case CDC:
if (ljchar_create(charcode, &infc) == ERROR)
{
ljchar_free_all();
fclose(infp);
fclose(outfp);
return;
}
break;
}
}
if (npasses > 0)
{
for (charcode = 0; charcode < sizeofarray(ljchars); charcode++)
{
if (ljchars[charcode].bitmap != NULL)
{
/* output the character code command */
outfc.command_type = CCC;
outfc.number = charcode;
if (font_command_write(outfp, &outfc) == ERROR)
{
fprintf(stderr, ERROR_FILE_WRITE_FAILED, os_dir, os_file);
ljchar_free_all();
fclose(infp);
fclose(outfp);
return;
}
/* convert the character descriptor and bitmap */
if (cdc_dj_to_lj(&ljchars[charcode], &outfc) == ERROR)
{
ljchar_free_all();
fclose(infp);
fclose(outfp);
return;
}
/* output the character descriptor and bitmap */
if (font_command_write(outfp, &outfc) == ERROR)
{
fprintf(stderr, ERROR_FILE_WRITE_FAILED, os_dir, os_file);
ljchar_free_all();
fclose(infp);
fclose(outfp);
return;
}
}
}
}
if (npasses == 0 || r != EOF)
/* error scenarios: (npasses == 0) means no font descriptor found,
probably processing a text file; (r != EOF) means a font
command escape sequence wasn't read in correctly, probably
processing a binary file or a truncated soft font file */
fprintf(stderr, ERROR_FILE_READ_FAILED, os_dir, os_file);
else
{
fprintf(stderr, OK_JETD2L, os_dir, os_file, outpath);
}
ljchar_free_all();
fclose(infp);
fclose(outfp);
}
main(argc, argv)
int argc;
char *argv[];
{
char c;
/* stop getopt() printing errors */
opterr = FALSE;
while ((c = getopt(argc, argv, "t:h")) != EOF)
{
switch (c)
{
case 't':
strncpy(output_suffix+1, optarg, SUFFIX_MAX-2);
output_suffix[SUFFIX_MAX-1] = '\0';
break;
case 'h':
case '?':
/* help required, or invalid option specified */
usage_wrong();
}
}
/* must specify at least one file */
if (optind >= argc)
usage_wrong();
/* process file arguments */
if (os_findfiles((argc - optind), &argv[optind]) == ERROR)
fprintf(stderr, ERROR_OUT_OF_HEAP);
while (os_getfile() != EOF)
jetd2l();
return(0);
}